#include "weaveinstructionlogic.h"
#include "GeneralDefine.h"
#include "programengine.h"
#include "messagelog.h"
WeaveInstructionLogic::WeaveInstructionLogic(QString configFilePathIn, int robotIdIn, ProgramSet *programSetIn,
                             RobotIo *ioControllerIn, ProgramEngine *programEngineIn,McControllerThread *programMcControllerIn)
{
    programSet=programSetIn;
    robotId=robotIdIn;
    ioController=ioControllerIn;
    programEngine=programEngineIn;
    configFilePath=configFilePathIn;
    programMcController=programMcControllerIn;

    QString readComent;
    int tmpReturn = readConfigFile(configFilePathIn,readComent);
    if(1!=tmpReturn)
    {
        addMsg( ENUM_MSG_ERROR, "ProgramEngine", "WeldStartInstructionLogic",  12800, robotId ,0,0,0,0,readComent);
    }
    else
    {
        programMcController->mcControllerInterpreter->setWaveAcceleration(accRatio,velRatio,true);
    }

}

E_PROGRAM_LOOP_RESULT WeaveInstructionLogic::startWeave(int programNum, WeaveInstruction weaveInstruct)
{
    qDebug()<<"startWeave";
    WeaveMotionCondition tmpWeaveInfo;
    bool isContain=false;
    usingMutex.lock();
    for(int i=0;i<weaveConditionList.size();i++)
    {
        if(weaveConditionList[i].id==weaveInstruct.weaveConditionIndex)
        {
            tmpWeaveInfo=weaveConditionList[i];
            isContain=true;
            break;
        }
    }
    usingMutex.unlock();
    if(false==isContain)
    {
        addMsg( ENUM_MSG_ERROR, "ProgramEngine", "WeldStartInstructionLogic",  12801,
                            robotId ,weaveInstruct.weaveConditionIndex);
        return E_PROGRAM_LOOP_RESULT_ERROR;
    }

    E_WAVE_STATUS tmpwaveStatus=programMcController->mcControllerInterpreter->getWaveMotionStatus();
    if(E_WAVE_STATUS_STOPED!=tmpwaveStatus)
    {
        addMsg( ENUM_MSG_ERROR, "ProgramEngine", "WeldStartInstructionLogic",  12803, robotId );
        return E_PROGRAM_LOOP_RESULT_ERROR;
    }

    programMcController->mcControllerInterpreter->setWaveMotionInfo(tmpWeaveInfo);
    programMcController->mcControllerInterpreter->startWave();
    programEngine->calculateNextLineToRun(programNum);

    return programEngine->isTheLastInstruction(programNum);
}

E_PROGRAM_LOOP_RESULT WeaveInstructionLogic::startWeaveEnd(int programNum, WeaveEndInstruction weaveEndInstruct)
{
    qDebug()<<"startWeaveEnd";
    programMcController->mcControllerInterpreter->stopWave();

    //wait
    int maxWait=100;
    E_WAVE_STATUS tmpwaveStatus;
    do
    {
        usleep(50000);
        tmpwaveStatus=programMcController->mcControllerInterpreter->getWaveMotionStatus();

        maxWait-=1;
        if(0>maxWait)
        {
            addMsg( ENUM_MSG_ERROR, "ProgramEngine", "WeaveInstructionLogic",  12802, robotId );
            return E_PROGRAM_LOOP_RESULT_ERROR;
        }

        int tmpEnginStatus=programEngine->getEngineStatue();
        if(ENUM_COMMAND_RESET == tmpEnginStatus || ENUM_COMMAND_CEASE ==tmpEnginStatus)
        {
           return E_PROGRAM_LOOP_RESULT_CEASE_STOP;
        }


    }
    while(E_WAVE_STATUS_STOPED!=tmpwaveStatus);

    programEngine->calculateNextLineToRun(programNum);

    return programEngine->isTheLastInstruction(programNum);
}

int WeaveInstructionLogic::reset()
{
    E_WAVE_STATUS tmpwaveStatus=programMcController->mcControllerInterpreter->getWaveMotionStatus();
    if(E_WAVE_STATUS_STOPED!=tmpwaveStatus)
    {
        programMcController->mcControllerInterpreter->stopWave();
    }
    return 1;

}

int WeaveInstructionLogic::getWeaveMotionConditionInfo(std::vector<WeaveMotionCondition> &infoOut)
{
    usingMutex.lock();
    infoOut=weaveConditionList;
    usingMutex.unlock();
    return 1;
}

int WeaveInstructionLogic::setWeaveMotionConditionInfo(WeaveMotionCondition infoIn)
{
    usingMutex.lock();
    for(int i=0;i<weaveConditionList.size();i++)
    {
        if(weaveConditionList[i].id==infoIn.id)
        {
            weaveConditionList[i]=infoIn;
            usingMutex.unlock();
            return writeWeaveMotionConditionInfo(configFilePath,infoIn);
        }
    }
    usingMutex.unlock();
    return 0;
}

int WeaveInstructionLogic::writeWeaveMotionConditionInfo(QString filePathIn, WeaveMotionCondition weldCondition)
{

    DomParser domparser;
    bool ok = domparser.openXml(filePathIn, QIODevice::ReadWrite);
    if( !ok )
    {
        qDebug() << "WeaveInstructionLogic::readConfigFile ==== 配置文件打开失败：" << configFilePath;
        return -1;
    }

    QDomNode domNode_f = domparser.findSubNode(domparser.getRootDomElement(), "conditionsConfig", ok );
    if( !ok )
    {
        qDebug() << "WeaveInstructionLogic::readConfigFile ==== 读取conditionsConfig结点失败：" << configFilePath;
        return -2;
    }

    QDomNodeList itemList = domNode_f.childNodes();

    for(int i=0;i<itemList.count();i++){
        if(weldCondition.id==i){
            domparser.writeXml(domparser.findSubNode(itemList.at(i), "id", ok ), weldCondition.id);
            if( !ok )
            {
                return -2;
            }

            domparser.writeXml(domparser.findSubNode(itemList.at(i), "motionStyle", ok ), weldCondition.motionStyle);
            if( !ok )
            {
                return -2;
            }

            domparser.writeXml(domparser.findSubNode(itemList.at(i), "frequency", ok ),  weldCondition.frequency);
            if( !ok )
            {
                return -2;
            }

            domparser.writeXml(domparser.findSubNode(itemList.at(i), "width", ok ),  weldCondition.width);
            if( !ok )
            {
                return -2;
            }

            domparser.writeXml(domparser.findSubNode(itemList.at(i), "width_move", ok ),  weldCondition.width_move);
            if( !ok )
            {
                return -2;
            }

            domparser.writeXml(domparser.findSubNode(itemList.at(i), "height", ok ),  weldCondition.height);
            if( !ok )
            {
                return -2;
            }

            domparser.writeXml(domparser.findSubNode(itemList.at(i), "isHaltAtEdge", ok ),  weldCondition.isHaltAtEdge);
            if( !ok )
            {
                return -2;
            }

            domparser.writeXml(domparser.findSubNode(itemList.at(i), "leftHaltTime", ok ), weldCondition.leftHaltTime);
            if( !ok )
            {
                return -2;
            }

            domparser.writeXml(domparser.findSubNode(itemList.at(i), "rightHaltTime", ok ),  weldCondition.rightHaltTime);
            if( !ok )
            {
                return -2;
            }

            domparser.writeXml(domparser.findSubNode(itemList.at(i), "rotateAngle_x", ok ),  weldCondition.rotateAngle_x);
            if( !ok )
            {
                return -2;
            }

            domparser.writeXml(domparser.findSubNode(itemList.at(i), "rotateAngle_z", ok ),  weldCondition.rotateAngle_z);
            if( !ok )
            {
                return -2;
            }
        }
    }

    domparser.closeXml(true);

    return 1;
}

int WeaveInstructionLogic::readConfigFile(QString filePathIn, QString &readComent)
{

    DomParser domparser;
    bool ok = domparser.openXml(filePathIn, QIODevice::ReadOnly);
    if( !ok )
    {
        qDebug() << "WeaveInstructionLogic::readConfigFile ==== 配置文件打开失败：" << configFilePath;
        return -1;
    }

    QDomNode domNode_f = domparser.findSubNode(domparser.getRootDomElement(), "conditionsConfig", ok );
    if( !ok )
    {
        qDebug() << "WeaveInstructionLogic::readConfigFile ==== 读取conditionsConfig结点失败：" << configFilePath;
        return -2;
    }

    QDomNodeList itemList = domNode_f.childNodes();

    for(int i=0;i<itemList.count();i++){
        struct WeaveMotionCondition weldCondition;
        // 读取并赋值
        domparser.readXml(domparser.findSubNode(itemList.at(i), "id", ok ), weldCondition.id);
        if( !ok )
        {
            readComent+=" id";
            return -2;
        }

        domparser.readXml(domparser.findSubNode(itemList.at(i), "motionStyle", ok ), weldCondition.motionStyle);
        if( !ok )
        {
            readComent+=" motionStyle";
            return -2;
        }

        domparser.readXml(domparser.findSubNode(itemList.at(i), "frequency", ok ), weldCondition.frequency);
        if( !ok )
        {
            readComent+=" frequency";
            return -2;
        }

        domparser.readXml(domparser.findSubNode(itemList.at(i), "width", ok ), weldCondition.width);
        if( !ok )
        {
            readComent+=" width";
            return -2;
        }

        domparser.readXml(domparser.findSubNode(itemList.at(i), "width_move", ok ), weldCondition.width_move);
        if( !ok )
        {
            readComent+=" width_move";
            return -2;
        }

        domparser.readXml(domparser.findSubNode(itemList.at(i), "height", ok ), weldCondition.height);
        if( !ok )
        {
            readComent+=" height";
            return -2;
        }

        domparser.readXml(domparser.findSubNode(itemList.at(i), "isHaltAtEdge", ok ), weldCondition.isHaltAtEdge);
        if( !ok )
        {
            readComent+=" isHaltAtEdge";
            return -2;
        }


        domparser.readXml(domparser.findSubNode(itemList.at(i), "leftHaltTime", ok ), weldCondition.leftHaltTime);
        if( !ok )
        {
            readComent+=" leftHaltTime";
            return -2;
        }

        domparser.readXml(domparser.findSubNode(itemList.at(i), "rightHaltTime", ok ), weldCondition.rightHaltTime);
        if( !ok )
        {
            readComent+=" rightHaltTime";
            return -2;
        }

        domparser.readXml(domparser.findSubNode(itemList.at(i), "rotateAngle_x", ok ), weldCondition.rotateAngle_x);
        if( !ok )
        {
            readComent+=" rotateAngle_x";
            return -2;
        }

        domparser.readXml(domparser.findSubNode(itemList.at(i), "rotateAngle_z", ok ), weldCondition.rotateAngle_z);
        if( !ok )
        {
            readComent+=" rotateAngle_z";
            return -2;
        }

        weaveConditionList.push_back(weldCondition);
    }

    domNode_f = domparser.findSubNode(domparser.getRootDomElement(), "commonConfig", ok );
    if( !ok )
    {
        readComent+=" commonConfig";
        return -2;
    }

    domparser.readXml(domparser.findSubNode(domNode_f, "accRatio", ok ), accRatio);
    if( !ok )
    {
        readComent+=" accRatio";
        return -2;
    }

    domparser.readXml(domparser.findSubNode(domNode_f, "velRatio", ok ), velRatio);
    if( !ok )
    {
        readComent+=" velRatio";
        return -2;
    }

    domparser.closeXml();

    return 1;
}



void WeaveInstructionLogic::addMsg(int messageLevel, string componentName,
                                       string messageType, int messageCode, int robotId, int parameter1,
                                       int parameter2, int parameter3, int parameter4, QString message)
{
    Message tmpMsg;
    tmpMsg.MessageLevel = messageLevel;
    tmpMsg.componentClassName = componentName;
    tmpMsg.messageType = messageType;
    tmpMsg.robotId = robotId;
    tmpMsg.messageCode = messageCode;
   // tmpMsg.time = t1.tv_sec;


    QString infomationStr;

    switch(messageCode)
    {
    case 12803:
    {
        infomationStr =  QObject::tr("机器人:")  + QString::number(robotId);
        infomationStr = infomationStr + QObject::tr(",摆焊启动失败，请先终止上次摆焊")+message;
         break;
    }
    case 12802:
    {
        infomationStr =  QObject::tr("机器人:")  + QString::number(robotId);
        infomationStr = infomationStr + QObject::tr(",摆焊终止超时")+message;
         break;
    }
    case 12801:
    {
        infomationStr =  QObject::tr("机器人:")  + QString::number(robotId);
        infomationStr = infomationStr + QObject::tr(",摆焊参数号(%1)不存在").arg(parameter1)+message;
    }
        break;
    case 12800:
    {
        infomationStr =  QObject::tr("机器人:")  + QString::number(robotId);
        infomationStr = infomationStr + QObject::tr(",摆焊参数文件weaveConfig.xml读取失败,")+message;
    }
        break;



    default:
    {

    }
    }


    tmpMsg.MessageInformation = infomationStr.toStdString();

    // qDebug()<<"53444444444444444444444"<< tmpMsg.messageCode;
    MessageLog::getInstance()->addMessage(tmpMsg);
}
